<template>
  <div class="chessBox">
    <!-- 绘制棋盘 -->
    <canvas class="canvas" width="800" height="800"></canvas>
    <!-- 给每个点上添加点击事件 -->
    <div v-for="rowI in row" :key="rowI">
      <div class="clickDiv" v-for="colI in col" :key="colI" :style="{ 'top': (rowI * 50 - 15) + 'px', 'left': (colI * 50 - 15) + 'px' }" @click="clickDiv(rowI, colI)" />
    </div>
    <!-- 判断输赢 -->
    <el-card class="cardBox" v-if="winLine">
      <div class="cardItem">{{ winColor }} 获胜！ {{ orientWin }}</div>
      <!-- 重开一局 -->
      <div class="cardItem">
        <el-button class="startButt" @click="startGame">重开一局</el-button>
      </div>
    </el-card>
    <!-- 把赢的棋子直线连接起来 -->
    <canvas class="winCanvas" width="800" height="800" v-show="winLine"></canvas>

  </div>
</template>

<script>
export default {
  data() {
    return {
      gridSize: 50, // 定义变量保存小方格的尺寸
      row: 0, // 行数
      col: 0, // 列数
      nowColor: 'black', // 当前棋子的颜色
      resultArr: [], // 计算棋子的输赢的结果数组

      winColor: '', // 赢的棋子的颜色
      orientWin: '', // 赢的方位
      winOpsition: [], // 赢的棋子的位置

      winLine: false, // 把赢的棋子直线连接起来
    }
  },
  mounted() {
    this.getCanvas() // 绘制棋盘
    this.getChessArr() // 初始化棋子的颜色
  },
  methods: {
    // 绘制棋盘
    getCanvas() {
      let oCanvas = document.getElementsByClassName('canvas')[0] // 拿到canvas
      let oCtx = oCanvas.getContext('2d') // 从canvas中拿到绘图工具
      let gridSize = this.gridSize // 定义变量保存小方格的尺寸
      // 拿到canvas的宽高
      let canvasWidth = oCtx.canvas.width
      let canvasHeight = oCtx.canvas.height
      // 计算在垂直方向和水平方向可以绘制多少条横线
      this.row = Math.floor(canvasHeight / gridSize) - 1
      this.col = Math.floor(canvasWidth / gridSize) - 1
      // 绘制水平线
      for (let i = 0; i <= this.row; i++) {
        oCtx.beginPath()
        oCtx.moveTo(0, i * gridSize - 0.5)
        oCtx.lineTo(canvasWidth, i * gridSize - 0.5)
        oCtx.strokeStyle = '#C89870'
        oCtx.stroke()
      }
      // 绘制竖直线
      for (let i = 0; i <= this.col; i++) {
        oCtx.beginPath()
        oCtx.moveTo(i * gridSize - 0.5, 0)
        oCtx.lineTo(i * gridSize - 0.5, canvasHeight)
        oCtx.strokeStyle = '#C89870'
        oCtx.stroke()
      }
      // 绘制水平线 - 中间线
      oCtx.beginPath()
      oCtx.moveTo(0, canvasHeight / 2)
      oCtx.lineTo(canvasWidth, canvasHeight / 2)
      oCtx.strokeStyle = '#666'
      oCtx.stroke()
      // 绘制竖直线 - 中间线
      oCtx.beginPath()
      oCtx.moveTo(canvasWidth / 2, 0)
      oCtx.lineTo(canvasWidth / 2, canvasHeight)
      oCtx.strokeStyle = '#666'
      oCtx.stroke()
    },
    // 初始化棋子的颜色
    getChessArr() {
      for (let r = 1; r <= this.row; r++) {
        for (let c = 1; c <= this.col; c++) { this.resultArr.push([[r, c], 'gray']) }
      }
    },
    // 给每个点上添加点击事件
    clickDiv(rowI, colI) {
      console.log('点击的位置-----', rowI, colI)
      // 在点击的位置放置黑色或者红色棋子
      let chessBox = document.getElementsByClassName('chessBox')[0]
      let chessDiv = document.createElement('div')
      chessDiv.className = 'chessDiv'
      chessBox.appendChild(chessDiv)
      chessDiv.style.width = '30px'
      chessDiv.style.height = '30px'
      chessDiv.style.borderRadius = '15px'
      chessDiv.style.background = this.nowColor
      chessDiv.style.position = 'absolute'
      chessDiv.style.top = (rowI * this.gridSize - 15) + 'px'
      chessDiv.style.left = (colI * this.gridSize - 15) + 'px'
      chessDiv.style.zIndex = '5'
      // this.resultArr 对应的位置颜色设置为当前下的棋子的颜色
      let resultIndex = this.resultArr.findIndex(item => { return item[0][0] == rowI && item[0][1] == colI })
      this.resultArr[resultIndex][1] = this.nowColor
      // 计算是否有连续五个棋子颜色一样的
      let posX = this.resultArr[resultIndex][0][0]
      let posY = this.resultArr[resultIndex][0][1]
      console.log('点击的位置-----', posX, posY)
      // --------------------------------------计算横向的 horiResArr---------------------------------------
      let horiArr = [[posX, posY - 4], [posX, posY - 3], [posX, posY - 2], [posX, posY - 1], [posX, posY], [posX, posY + 1], [posX, posY + 2], [posX, posY + 3], [posX, posY + 4]]
      let horiPosArr = horiArr.filter(item => { return item[1] > 0 && item[1] <= this.col })
      let horiResArr = []
      horiPosArr.forEach(pos => {
        let result = this.resultArr.filter(item => { return pos[0] == item[0][0] && pos[1] == item[0][1] })[0]
        horiResArr.push(result)
      })
      for (let i = 0; i < horiResArr.length - 4; i++) {
        let resColorArr = horiResArr.slice(i, i + 5)
        let resultNum = 0
        let whiteOrBlack = resColorArr[0][1]
        resColorArr.forEach(item => {
          if (item[1] == whiteOrBlack) { resultNum++ }
          if (resultNum == 5) {
            this.winColor = (whiteOrBlack == 'whiteOrBlack') ? '白色' : '黑色'
            this.orientWin = '横向'
            this.getWinCanvas(resColorArr)
            return
          }
        })
      }
      // --------------------------------------计算竖向的 vertiResArr---------------------------------------
      let vertiArr = [[posX - 4, posY], [posX - 3, posY], [posX - 2, posY], [posX - 1, posY], [posX, posY], [posX + 1, posY], [posX + 2, posY], [posX + 3, posY], [posX + 4, posY]]
      let vertiPosArr = vertiArr.filter(item => { return item[0] > 0 && item[0] <= this.row })
      let vertiResArr = []
      vertiPosArr.forEach(pos => {
        let result = this.resultArr.filter(item => { return pos[0] == item[0][0] && pos[1] == item[0][1] })[0]
        vertiResArr.push(result)
      })
      for (let i = 0; i < vertiResArr.length - 4; i++) {
        let resColorArr = vertiResArr.slice(i, i + 5)
        let resultNum = 0
        let whiteOrBlack = resColorArr[0][1]
        resColorArr.forEach(item => {
          if (item[1] == whiteOrBlack) { resultNum++ }
          if (resultNum == 5) {
            this.winColor = (whiteOrBlack == 'whiteOrBlack') ? '白色' : '黑色'
            this.orientWin = '竖向'
            this.getWinCanvas(resColorArr)
            return
          }
        })
      }
      // --------------------------------------计算斜向左 slantLResArr---------------------------------------
      let slantLArr = [[posX - 4, posY + 4], [posX - 3, posY + 3], [posX - 2, posY + 2], [posX - 1, posY + 1], [posX, posY], [posX + 1, posY - 1],
      [posX + 2, posY - 2], [posX + 3, posY - 3], [posX + 4, posY - 4]]
      let slantLPosArr = slantLArr.filter(item => { return item[0] > 0 && item[0] <= this.row && item[1] > 0 && item[1] <= this.col })
      let slantLResArr = []
      slantLPosArr.forEach(pos => {
        let result = this.resultArr.filter(item => { return pos[0] == item[0][0] && pos[1] == item[0][1] })[0]
        slantLResArr.push(result)
      })
      for (let i = 0; i < slantLResArr.length - 4; i++) {
        let resColorArr = slantLResArr.slice(i, i + 5)
        let resultNum = 0
        let whiteOrBlack = resColorArr[0][1]
        resColorArr.forEach(item => {
          if (item[1] == whiteOrBlack) { resultNum++ }
          if (resultNum == 5) {
            this.winColor = (whiteOrBlack == 'whiteOrBlack') ? '白色' : '黑色'
            this.orientWin = '斜向左侧'
            this.getWinCanvas(resColorArr)
            return
          }
        })
      }
      // --------------------------------------计算斜向右 slantRResArr---------------------------------------
      let slantRArr = [[posX - 4, posY - 4], [posX - 3, posY - 3], [posX - 2, posY - 2], [posX - 1, posY - 1], [posX, posY], [posX + 1, posY + 1],
      [posX + 2, posY + 2], [posX + 3, posY + 3], [posX + 4, posY + 4]]
      let slantRPosArr = slantRArr.filter(item => { return item[0] > 0 && item[0] <= this.row && item[1] > 0 && item[1] <= this.col })
      let slantRResArr = []
      slantRPosArr.forEach(pos => {
        let result = this.resultArr.filter(item => { return pos[0] == item[0][0] && pos[1] == item[0][1] })[0]
        slantRResArr.push(result)
      })
      for (let i = 0; i < slantRResArr.length - 4; i++) {
        let resColorArr = slantRResArr.slice(i, i + 5)
        let resultNum = 0
        let whiteOrBlack = resColorArr[0][1]
        resColorArr.forEach(item => {
          if (item[1] == whiteOrBlack) { resultNum++ }
          if (resultNum == 5) {
            this.winColor = (whiteOrBlack == 'whiteOrBlack') ? '白色' : '黑色'
            this.orientWin = '斜向右侧'
            this.getWinCanvas(resColorArr)
            return
          }
        })
      }
      // 设置下个棋子的颜色
      if (this.nowColor == 'white') {
        this.nowColor = 'black'
      } else {
        this.nowColor = 'white'
      }
    },
    // 把赢的棋子直线连接起来
    getWinCanvas(winArr) {
      console.log('赢的棋子------位置', winArr)
      this.winLine = true
      let oCanvas = document.getElementsByClassName('winCanvas')[0] // 拿到canvas
      let oCtx = oCanvas.getContext('2d') // 从canvas中拿到绘图工具
      let gridSize = this.gridSize // 定义变量保存小方格的尺寸
      oCtx.beginPath()
      oCtx.moveTo(winArr[0][0][1] * gridSize, winArr[0][0][0] * gridSize)
      oCtx.lineTo(winArr[4][0][1] * gridSize, winArr[4][0][0] * gridSize)
      oCtx.lineWidth = 5
      oCtx.strokeStyle = 'red'
      oCtx.lineJoin = "round"
      oCtx.stroke()
    },
    // 重开一局
    startGame() {
      this.winLine = false
      // 清空所有棋子
      let chessBox = document.getElementsByClassName('chessBox')[0]
      let chessDivs = document.getElementsByClassName('chessDiv')
      let total = chessDivs.length
      for (let i = 0; i < total; i++) { chessBox.removeChild(chessDivs[0]) }
      // 清空 赢的棋子连线 1. 重置画布的宽高 / 2. 用 clearRect 方法清除画布
      let oCanvas = document.getElementsByClassName('winCanvas')[0] // 拿到canvas
      let w = oCanvas.width
      let h = oCanvas.height
      oCanvas.width = w
      oCanvas.height = h
      // oCtx.clearRect(0, 0, oCanvas.width, oCanvas.height)
      this.nowColor = 'black' // 当前棋子的颜色
      this.resultArr = [] // 计算棋子的输赢的结果数组
      this.winColor = '' // 赢的棋子的颜色
      this.orientWin = '' // 赢的方位
      this.getCanvas()
      // 初始化棋子的颜色
      this.getChessArr()
    }
  }

}
</script>

<style scoped>
.chessBox {
  width: 1400px;
  height: 800px;
  border: 1px solid #666;
  padding: 0px;
  /* margin: 10px; */
  position: relative;
  margin-top: -10px;
  margin-left: -20px;
}

.canvas {
  background: #fee8c5;
  /* color: white; */
  border-right: 1px solid #666;
  position: absolute;
}

.clickDiv {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  /* background-color: #bbb; */
  position: absolute;
}

.cardBox {
  width: 400px;
  height: 200px;
  background: pink;
  border: 1px solid pink;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
  position: absolute;
  top: 100px;
  right: 50px;
}

.cardItem {
  width: 350px;
  height: 60px;
  font-size: 27px;
  line-height: 60px;
  text-align: center;
}

.startButt {
  width: 120px;
  font-size: 20px;
  color: skyblue;
}

.winCanvas {
  background: rgba(102, 102, 102, 0.2);
  position: absolute;
  z-index: 10;
}
</style>